/**
 * 
 */
package org.totalbeginner.tutorial;

import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.Test;

/**
 * @author Ibraheem.Abdullah
 *
 */
public class MyLibraryTest {

	private MyLibrary m1;
	private Book b1;
	private Book b2;
	private Person p1;
	private Person p2;

	@Test
	public void testMyLibrary() {
		MyLibrary m1 = new MyLibrary("IbyLib");
		
		assertEquals("IbyLib", m1.name);
		assertTrue(m1.Books instanceof ArrayList);
		assertTrue(m1.people instanceof ArrayList);
	}

	public void setup() {
		m1 = new MyLibrary("Test Lib");
		b1 = new Book("Book1");
		b2 = new Book("Book2");
		p1 = new Person();
		p2 = new Person();
		p1.setName("Ibr");
		p2.setName("Qud");		
	}
	
	@Test
	public void testAddBook() {
		setup();
		assertEquals(0, m1.getBooks().size());
		m1.addBook(b1);
		m1.addBook(b2);
		assertEquals(2, m1.getBooks().size());
		assertEquals(0, m1.getBooks().indexOf(b1));
		assertEquals(1, m1.getBooks().indexOf(b2));
		
		m1.removeBook(b1);
		assertEquals(1, m1.getBooks().size());
		assertEquals(0, m1.getBooks().indexOf(b2));
		
		m1.removeBook(b2);
		assertEquals(0, m1.getBooks().size());
		
	}
	
	@Test
	public void testAddPerson() {
		setup();
		assertEquals(0, m1.getPeople().size());
		m1.addPerson(p1);
		m1.addPerson(p2);
		assertEquals(2, m1.getPeople().size());
		assertEquals(0, m1.getPeople().indexOf(p1));
		assertEquals(1, m1.getPeople().indexOf(p2));
		
		m1.removePerson(p1);
		assertEquals(1, m1.getPeople().size());
		assertEquals(0, m1.getPeople().indexOf(p2));
		
		m1.removePerson(p2);
		assertEquals(0, m1.getPeople().size());
		
	}
	
	@Test
	public void testCheckMethods() {
		setup();
		assertTrue("Book fails to checkout...", m1.checkout(b1,p1));
		assertEquals("Ibr",	b1.getPerson().getName());
		assertFalse("Book was already checked out", m1.checkout(b1,p2));
		
		assertTrue("Book fails to chekin", m1.checkin(b1));
		assertFalse("Book was never checked out", m1.checkin(b2));
		
		setup();
		addToLibrary();
		p1.setMaximumBooks(1);
		assertTrue("First book chekcout failed....",m1.checkout(b1, p1));
		assertFalse("2nd Book should not have checked out...",m1.checkout(b2, p1));
		
	}
	
	@Test
	public void testgetNumberOfCheckedoutBooksForPerson(){
		setup();
		addToLibrary();
		assertEquals(0, m1.getNumberOfCheckedoutBooksForPerson(p1));
		assertTrue("checkout failed...",m1.checkout(b1, p1));
		assertEquals(1, m1.getNumberOfCheckedoutBooksForPerson(p1));
		assertTrue("checkout failed...",m1.checkout(b2, p1));
		assertEquals(2, m1.getNumberOfCheckedoutBooksForPerson(p1));
		
	}
	
	@Test
	public void testGetBooksForPerson(){
		setup();
		addToLibrary();
		assertEquals(0, m1.getBooksForPerson(p1).size());
		
		assertTrue("checkout failed...",m1.checkout(b1, p1));
		assertEquals(1, m1.getBooksForPerson(p1).size());
		assertEquals(0, m1.getBooksForPerson(p1).indexOf(b1));
		
		assertTrue("checkout failed...",m1.checkout(b2, p1));
		ArrayList<Book> bookList = m1.getBooksForPerson(p1);
		assertEquals(2, bookList.size());
		assertEquals(0, bookList.indexOf(b1));
		assertEquals(1, bookList.indexOf(b2));		
		
	}

	public void addToLibrary() {
		m1.addBook(b1);
		m1.addBook(b2);
		m1.addPerson(p1);
		m1.addPerson(p2);
	}
	
	@Test
	public void testGetAvailableBooks() {
		setup();
		addToLibrary();
		assertEquals(2, m1.getAvailableBooks().size());
		assertEquals(1, m1.getAvailableBooks().indexOf(b2));
		
		m1.checkout(b1, p1);
		assertEquals(1, m1.getAvailableBooks().size());
		assertEquals(0, m1.getAvailableBooks().indexOf(b2));
		
		m1.checkout(b2, p1);
		assertEquals(0, m1.getAvailableBooks().size());		
	}
	
	@Test
	public void testGetUnAvailableBooks() {
		setup();
		addToLibrary();
		assertEquals(0, m1.getUnAvailableBooks().size());
		
		m1.checkout(b1, p1);
		assertEquals(1, m1.getUnAvailableBooks().size());
		assertEquals(0, m1.getUnAvailableBooks().indexOf(b1));
		
		m1.checkout(b2, p1);
		assertEquals(2, m1.getUnAvailableBooks().size());
		assertEquals(0, m1.getUnAvailableBooks().indexOf(b1));
		assertEquals(1, m1.getUnAvailableBooks().indexOf(b2));
		
	}
	
	@Test
	public void testToString() {
		setup();
		addToLibrary();
		assertEquals("Test Lib: 2 Books, 2 People.", m1.toString() );
	}
}
